package com.bossly.metro.Views;

import java.util.ArrayList;
import java.util.Hashtable;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import com.bossly.metro.R;
import com.bossly.metro.dom.Station;

public class DirectionView extends View {
	Drawable[] mSmallImages;
	private int maxWidth = 0;
	private int maxHeight = 0;

	Paint mTextPaint;
	int[] m_points;
	int[] m_lines;
	int m_padding = 5;
	int m_textPadding = 20;

	ArrayList<Station> direction;
	Hashtable<Integer, Drawable> mDrawables = null;

	public DirectionView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initialize();
	}

	public DirectionView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initialize();
	}

	public DirectionView(Context context) {
		super(context);
		initialize();
	}

	private void initialize() {
		Resources res = getResources();

		mTextPaint = new Paint();
		mTextPaint.setColor(Color.WHITE);
		mTextPaint.setTextSize(res.getDimension(R.dimen.station_name_size));
		m_padding = (int) res.getDimension(R.dimen.station_padding);
		m_textPadding = 20;

		m_points = new int[] { R.drawable.point_green, R.drawable.point_red,
				R.drawable.point_yellow, R.drawable.point_blue };

		m_lines = new int[] { R.drawable.line_green, R.drawable.line_red,
				R.drawable.line_yellow, R.drawable.line_blue };

		Drawable dBridge = getDrawable(R.drawable.bridge);
		maxWidth = dBridge.getIntrinsicWidth();

		Drawable dPoint = getDrawable(R.drawable.point_green);
		maxHeight = dPoint.getIntrinsicHeight();
	}

	private Drawable getDrawable(int id) {
		Drawable result;
		final Resources res = getContext().getResources();

		if (mDrawables == null)
			mDrawables = new Hashtable<Integer, Drawable>();

		if (!mDrawables.containsKey(id)) {
			result = res.getDrawable(id);
			mDrawables.put(id, result);
		} else {
			result = mDrawables.get(id);
		}

		return result;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int height = 0;
		int stations = direction.size();

		height = (int) (stations * (maxHeight + m_padding));
		setMeasuredDimension(widthMeasureSpec,
				resolveSize(height, heightMeasureSpec));
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (direction != null) {
			int topY = getPaddingTop() + getTop();
			int bottomY = topY;
			Station station;
			Drawable d;

			int x = 0;
			int line = -1;
			int color = -1;

			// draw lines and bridges
			for (int i = 0, length = direction.size(); i < length; i++) {
				station = direction.get(i);

				if (line >= 0 && line != station.getLine()) {
					color++;

					// draw line
					d = getDrawable(m_lines[color]);
					x = maxWidth / 2 - d.getIntrinsicWidth() / 2;

					if (color != 0)
						d.setBounds(x, topY - m_padding + 7,
								x + d.getIntrinsicWidth(), bottomY);
					else
						d.setBounds(x, topY + m_padding,
								x + d.getIntrinsicWidth(), bottomY);

					d.draw(canvas);

					// draw bridge
					d = getDrawable(R.drawable.bridge);
					x = maxWidth / 2 - d.getIntrinsicWidth() / 2 + 1;
					int boff = maxHeight + 2 * m_padding + 3;
					topY = bottomY - boff + d.getIntrinsicHeight();

					d.setBounds(x, bottomY - boff, x + d.getIntrinsicWidth(),
							topY);
					d.draw(canvas);
				}

				// calc line long
				bottomY += maxHeight + m_padding;

				if (i == length - 1) {
					// draw last line
					d = getDrawable(m_lines[++color]);
					x = maxWidth / 2 - d.getIntrinsicWidth() / 2;
					bottomY = bottomY - m_padding - maxHeight / 2;

					if (color != 0)
						d.setBounds(x, topY - m_padding + 7,
								x + d.getIntrinsicWidth(), bottomY);
					else
						d.setBounds(x, topY + m_padding,
								x + d.getIntrinsicWidth(), bottomY);

					d.draw(canvas);
				}

				line = station.getLine();
			}

			topY = getPaddingTop() + getTop();
			color = -1;
			line = -1;

			// draw points
			for (int i = 0, length = direction.size(); i < length; i++) {
				station = direction.get(i);

				if (line != station.getLine())
					color++;

				d = getDrawable(m_points[color]);
				x = maxWidth / 2 - d.getIntrinsicWidth() / 2;
				d.setBounds(x, topY, x + d.getIntrinsicWidth(),
						topY + d.getIntrinsicHeight());

				d.draw(canvas);

				// draw text
				canvas.drawText(station.getName(), d.getIntrinsicWidth()
						+ m_textPadding, topY + d.getIntrinsicHeight() - 8,
						mTextPaint);

				topY += d.getIntrinsicHeight() + m_padding;

				line = station.getLine();
			}
		}
	}

	public void setDirections(ArrayList<Station> findDirections) {
		direction = findDirections;
		requestLayout();
	}
}
